/**
 * Frame de l'application.
 * 
 * @author Marie-Hélène Goddet, Damien Finck, Cédric Schaller
 * 
 */
package gui;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;

import utils.Debug;
import utils.Resources;
import fastwriting.Contact;
import fastwriting.Dico;
import fastwriting.FastWriting;

@SuppressWarnings("serial")
public class IHM extends JFrame {
	
	protected JLoad jload;
	protected JHome jhome;
	protected JContact jcontact;
	protected JPanel jgeneral;
		protected JScreen jscreen;protected JDico jdico;protected JOptions joptions;
		protected JClavier jclavier;
	protected JSend jsend;
	
	protected JPopupMenu jpopopMenu;
	protected JMenuItem jmi_cancel,jmi_dico,jmi_lower,jmi_upper,jmi_first,jmi_cut,jmi_copy,jmi_paste,jmi_delete,jmi_selectAll;
	//protected String pressePapier;
	
	/**
	 * Constructeur
	 * @param titre Titre de la frame
	 * @param dico Le dictionnaire à utiliser
	 */
	public IHM(String titre) {
		/** Titre **/
		super(titre);
		
		Debug.addLog("Lecture Dictionnaire", Debug.LOG_INFO, "all");
		Dico dico = new Dico();
		
		/** Look & Feel **/
		LookAndFeel.setLookAndFeel(this,new Integer(Integer.parseInt(FastWriting.config.get("Themes").get("Theme").toString())));
		/** Evénements **/
		ActionListener action = new Evenements(this,dico);
		MouseListener mouse = new Evenements(this,dico);
		MouseMotionListener mouseMotion = new Evenements(this,dico);
		CaretListener caret = new Evenements(this,dico);
		/** Interface **/
		creeJPLoad(action);						// Chargement
		creeJPHome(action); // Menu principale
		creeJPContact(action); // Choix des destinataires
		creeJPGeneral(dico,action,mouse,mouseMotion,caret); // JP_Screen + jc_clavier
		creeJPSend(action); // Récapitulatif + envoi des mails
		creePopupMenu(action); // crée la popup du clic droit
		
		if (!FastWriting.COPYRIGHT)
			this.add(this.jload); // Montage de la première interface
		else
			this.add(this.jgeneral);
		
		this.jgeneral.addMouseListener(mouse);
		this.jgeneral.addMouseMotionListener(mouseMotion);
		/** Fenêtre **/
		creeFenetre();
		
		this.setCursor(new Cursor(Cursor.HAND_CURSOR));
	}
	/**
	 * Crée le panel de chargement
	 * @param action événement généré
	 */
	public void creeJPLoad(ActionListener action) {
		/** Création des éléments     **/
		if (!FastWriting.COPYRIGHT) this.jload = new JLoad();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		if (!FastWriting.COPYRIGHT)
		this.jload.addActionListener(new ActionListener() {	// Changer d'interface JPLoad -> JPHome
			public void actionPerformed(ActionEvent arg0) {
				jload.setVisible(false);
				remove(jload);
				jhome.setVisible(true);
				add(jhome,BorderLayout.CENTER);
				//ihm.repaint();
			}
		});
	}
	/**
	 * Crée le panel d'accueuil
	 * @param action événement généré
	 */
	public void creeJPHome(ActionListener action) {
		/** Création des éléments     **/
		this.jhome = new JHome();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		this.jhome.addActionListener(new ActionListener() {	// Changer d'interface JHome -> JPContact
			public void actionPerformed(ActionEvent arg0) {
				jhome.setVisible(false);
				remove(jhome);
				jcontact.setVisible(true);
				add(jcontact,BorderLayout.CENTER);
				//ihm.repaint();
			}
		});
	}
	/**
	 * Crée le panel de contact
	 * @param action événement généré
	 */ 
	public void creeJPContact(ActionListener action) {
		/** Création des éléments     **/
		this.jcontact = new JContact();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		this.jcontact.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {		// Changer d'interface depuis JPContact
				if (arg0.getActionCommand().contains("next")) {			// => JPContact -> JPScreen+JPClavier
					jcontact.setVisible(false);
					remove(jcontact);
					jgeneral.setVisible(true);
					add(jgeneral,BorderLayout.CENTER);
					//ihm.repaint();
					
					jscreen.jta_ecran.requestFocus();	// curseur placé dans l'écran
					
				} else if (arg0.getActionCommand().contains("home")) {	// => JPContact -> JPHome
					jcontact.setVisible(false);
					remove(jcontact);
					jhome.setVisible(true);
					add(jhome,BorderLayout.CENTER);
					//ihm.repaint();
				}
			}
		});
	}
	/**
	 * Crée le panel général contenant tous les autres
	 * @param dico le dictionnaire
	 * @param action événement généré
	 * @param mouse événement généré
	 * @param mouseMotion événement généré
	 */
	public void creeJPGeneral(Dico dico,ActionListener action,MouseListener mouse,MouseMotionListener mouseMotion,CaretListener caret) {
		
		creeJPScreen(action,caret);
		creeJPDico(dico,action);
		creeJPOptions(action);
		creeJPClavier(action,mouse,mouseMotion);
		
		/** Création des éléments     **/
		this.jgeneral = new JPanel(new BorderLayout());
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		/** Montage des éléments      **/
		this.jgeneral.add(this.jscreen,BorderLayout.NORTH);
		this.jgeneral.add(this.jclavier,BorderLayout.SOUTH);
	}
	/**
	 * Crée le panel de l'écran
	 * @param action événement généré
	 */
	public void creeJPScreen(ActionListener action,CaretListener caret) {
		/** Création des éléments     **/
		this.jscreen = new JScreen();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		for (int i=0;i<JScreen.NB_CHOIX;i++) this.jscreen.jl_choix[i].addActionListener(action);		
		this.jscreen.addActionListener(new ActionListener() {	// Changer d'interface depuis JPScreen
			public void actionPerformed(ActionEvent arg0) {
				if (arg0.getActionCommand().contains("home")) {			// => JPScreen -> JPHome
					jgeneral.setVisible(false);
					remove(jgeneral);
					jhome.setVisible(true);
					add(jhome,BorderLayout.CENTER);
					//ihm.repaint();
				} else if (arg0.getActionCommand().contains("contact")) {	// => JPScreen -> JPContact
					jgeneral.setVisible(false);
					remove(jgeneral);
					jcontact.setVisible(true);
					add(jcontact,BorderLayout.CENTER);
					//ihm.repaint();
				} else if (arg0.getActionCommand().contains("send")) {	// => JPScreen -> JPSend
					jgeneral.setVisible(false);
					remove(jgeneral);
					jsend.setVisible(true);
					add(jsend,BorderLayout.CENTER);
					//ihm.repaint();
					
					// je charge la liste des destinataires
					String dest="";
					for (int i=0;i<jcontact.lm_to.size();i++) {
						if (jcontact.lm_to.get(i) instanceof Contact) {
							Contact c = (Contact)jcontact.lm_to.get(i);
							dest+=c.toStringWithMail()+", ";
							//FastWriting.destinataire.add(c);
						}
					}
					jsend.jta_to.setText(dest);
					// je charge le message
					jsend.jta_message.setText(jscreen.jta_ecran.getText());
				}
			}
		});
		this.jscreen.jta_ecran.addCaretListener(caret);
		this.jscreen.jta_ecran.addMouseListener(new MouseListener() {	// Majuscule : On/Off
			@Override
			public void mouseClicked(MouseEvent arg0) {
				//popupMenu
				String texte = jscreen.jta_ecran.getText();
				int tmp1,tmp2,tmp3;
				
				tmp1 = texte.substring(0,jscreen.jta_ecran.getCaretPosition()).lastIndexOf(' ');
				tmp2 = texte.substring(0,jscreen.jta_ecran.getCaretPosition()).lastIndexOf('\n');
				tmp3 = texte.substring(0,jscreen.jta_ecran.getCaretPosition()).lastIndexOf('.');
				
				int debutMot = Math.max(tmp1,Math.max(tmp2,tmp3));
				
				tmp1 = texte.indexOf(' ',jscreen.jta_ecran.getCaretPosition());
				tmp2 = texte.indexOf('\n',jscreen.jta_ecran.getCaretPosition());
				tmp3 = texte.indexOf('.',jscreen.jta_ecran.getCaretPosition());
				
				tmp1=(tmp1==-1)?jscreen.jta_ecran.getDocument().getLength():tmp1;
				tmp2=(tmp2==-1)?jscreen.jta_ecran.getDocument().getLength():tmp2;
				tmp3=(tmp3==-1)?jscreen.jta_ecran.getDocument().getLength():tmp3;
				
				int finMot= Math.min(tmp1,Math.min(tmp2,tmp3));
				
				finMot = (finMot == -1)?jscreen.jta_ecran.getDocument().getLength():finMot; //plus d'espaces, la fin est a la fin du texte
				
				jscreen.jta_ecran.setSelectionStart(debutMot+1);
				jscreen.jta_ecran.setSelectionEnd(finMot);
				
				jpopopMenu.show(arg0.getComponent(), arg0.getX(), arg0.getY());		// affichage de la PopupMenu
			}
			@Override
			public void mouseEntered(MouseEvent arg0) {
				if (arg0.getModifiers()==16 && Evenements.swyping) {
					if (!jclavier.jt_maj.isEnfonce() && FastWriting.wordWriting.size()<10) {
						jclavier.jt_maj.setEnfonce(true);
						//jc_clavier.jt_maj.setLock(true);
						ActionEvent e = new ActionEvent(jclavier.jt_maj,1001,"JClavier_MAJ");
						jclavier.jt_maj.getActionListener().actionPerformed(e);
						FastWriting.wordWriting.setMajDebut(true);
					}
				}
			}
			@Override
			public void mouseExited(MouseEvent arg0) {
				if (arg0.getModifiers()==16 && Evenements.swyping) {
					if (jclavier.jt_maj.isEnfonce() && !jclavier.jt_maj.isLock()) {
						jclavier.jt_maj.setEnfonce(false);
						//jc_clavier.jt_maj.setLock(false);
						ActionEvent e = new ActionEvent(jclavier.jt_maj,1001,"JClavier_MIN");
						jclavier.jt_maj.getActionListener().actionPerformed(e);
					}
				}
				Evenements.v.clear();
			}
			@Override
			public void mousePressed(MouseEvent arg0) {
				
			}
			@Override
			public void mouseReleased(MouseEvent arg0) {
			}
		});
		this.jscreen.jb_left.addActionListener(action);
		this.jscreen.jb_right.addActionListener(action);
	}
	/**
	 * Crée le panel permettant de modifier le dictionnaire personnel
	 * @param dico le dictionnaire
	 * @param action événement généré
	 */
	public void creeJPDico(Dico dico,ActionListener action) {
		/** Création des éléments     **/
		this.jdico = new JDico(dico);
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		this.jdico.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (arg0.getActionCommand().contains("select")) {
					if (jdico.jlst_list.getSelectedIndex()!=-1) {
						int start,end;
						start=jscreen.jta_ecran.getSelectionStart();
						end=jscreen.jta_ecran.getSelectionEnd();
						try {
							jscreen.jta_ecran.getDocument().remove(start, end-start);
							jscreen.jta_ecran.getDocument().insertString(jscreen.jta_ecran.getCaretPosition(),jdico.jlst_list.getSelectedValue().toString(),null);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					}
				}
			}
		});
	}
	/**
	 * Crée le panel permettant de changer les options
	 * @param action événement généré
	 */
	public void creeJPOptions(ActionListener action) {
		/** Création des éléments     **/
		this.joptions = new JOptions();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
	}
	/**
	 * Crée le panel du clavier
	 * @param action événement généré
	 * @param mouse événement généré
	 * @param mouseMotion événement généré
	 */
	public void creeJPClavier(ActionListener action,MouseListener mouse,MouseMotionListener mouseMotion) {
		/** Création des éléments     **/
		this.jclavier = new JClavier();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		for (int i=0;i<this.jclavier.jb_touches.length;i++) {
			this.jclavier.jb_touches[i].addActionListener(action);
			this.jclavier.jb_touches[i].addMouseListener(mouse);
			this.jclavier.jb_touches[i].addMouseMotionListener(mouseMotion);
		}
		this.jclavier.jt_space.addActionListener(action);
		this.jclavier.jt_enter.addActionListener(action);
		this.jclavier.jt_dico.addActionListener(action);
		this.jclavier.jt_options.addActionListener(action);
		
		this.jclavier.jt_backspace.addActionListener(action);
		this.jclavier.jt_backspace.addMouseListener(mouse);
		this.jclavier.jt_backspace.addMouseMotionListener(mouseMotion);
	}
	/**
	 * Crée le panel d'envoi
	 * @param action événement généré
	 */
	public void creeJPSend(ActionListener action) {
		/** Création des éléments     **/
		this.jsend = new JSend();
		/** Paramétrage des éléments  **/
		/** Action sur les éléments   **/
		this.jsend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (arg0.getActionCommand().contains("message")) {	
					jsend.setVisible(false);
					remove(jsend);
					jgeneral.setVisible(true);
					add(jgeneral,BorderLayout.CENTER);
					//ihm.repaint();
					jscreen.jta_ecran.requestFocus();	// curseur placé dans l'écran
				} else if (arg0.getActionCommand().contains("home")) {
					jsend.setVisible(false);
					remove(jsend);
					jhome.setVisible(true);
					add(jhome,BorderLayout.CENTER);
					//ihm.repaint();
				} else if (arg0.getActionCommand().contains("contact")) {
					jsend.setVisible(false);
					remove(jsend);
					jcontact.setVisible(true);
					add(jcontact,BorderLayout.CENTER);
					//ihm.repaint();
				}
			}
		});
	}
	/**
	 * Crée un menu Popup pour la modification des mots déjà ecris
	 * @param action événement généré
	 */
	public void creePopupMenu(ActionListener action) {
		/** Création des éléments     **/
		this.jmi_cancel    = new JMenuItem("Annuler");
		this.jpopopMenu    = new JPopupMenu();
		this.jmi_dico      = new JMenuItem("Ajouter au dico");
		this.jmi_lower     = new JMenuItem("en minuscule");
		this.jmi_upper     = new JMenuItem("en MAJUSCULE");
		this.jmi_first     = new JMenuItem("en Mixte");
		this.jmi_cut       = new JMenuItem("Couper");
		this.jmi_copy      = new JMenuItem("Copier");
		this.jmi_paste     = new JMenuItem("Coller");
		this.jmi_delete    = new JMenuItem("Supprimer mot");
		this.jmi_selectAll = new JMenuItem("Tout sélectionner");
		/** Paramétrage des éléments  **/
		//pressePapier = "";
		/** Action sur les éléments   **/
		this.jmi_cancel.addActionListener(action);
		this.jmi_dico.addActionListener(action);
		this.jmi_lower.addActionListener(action);
		this.jmi_upper.addActionListener(action);
		this.jmi_first.addActionListener(action);
		this.jmi_cut.addActionListener(action);
		this.jmi_copy.addActionListener(action);
		this.jmi_paste.addActionListener(action);
		this.jmi_delete.addActionListener(action);
		this.jmi_selectAll.addActionListener(action);
		/** Montage des éléments      **/
		jpopopMenu.add(this.jmi_cancel);
		jpopopMenu.add(this.jmi_dico);
		jpopopMenu.add(this.jmi_lower);
		jpopopMenu.add(this.jmi_upper);
		jpopopMenu.add(this.jmi_first);
		jpopopMenu.add(this.jmi_cut);
		jpopopMenu.add(this.jmi_copy);
		jpopopMenu.add(this.jmi_paste);
		jpopopMenu.add(this.jmi_delete);
		jpopopMenu.add(this.jmi_selectAll);
	}
	/**
	 * Crée la fenêtre
	 */
	public void creeFenetre() {
		this.setUndecorated(false);//Affichage de la barre de titre dans la fenêtre
		//this.setLayout(new FlowLayout());//Layout par défaut pour JFrame : BorderLayout
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Action de fermeture
		this.setResizable(false);//Redimensionnement de la fenêtre
		/* Dimension : choisir entre pack() ou setSize(width,height) */
		//this.pack();//Auto-dimensionner
		this.setSize(800,500);//Dimensionner la fenêtre. Dimensions réel sous Windows (794,477) (25:top;3:left;3:right;3:bottom)
		//ihm.setExtendedState(MAXIMIZED_BOTH);//Mettre en mode taille écran
		/* ----------------------------------------------------- */
		this.setLocationRelativeTo(null);//Positionner la fenêtre
		this.setIconImage(Resources.getImage("images/icon.png",getClass()));//Images dans la barre des tâches
		this.setVisible(true);//Rendre la fenêtre visible
		
	}
}